home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / leave.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  5KB  |  227 lines

  1. /* leave - tell the user when to go home    Author: Terrence W. Holm */
  2.  
  3. /* Usage:    leave [ [+] hhmm ]
  4.  *
  5.  * Author:    Terrence W. Holm
  6.  *
  7.  * Revision:
  8.  *        Fred van Kempen, MINIX User Group Holland
  9.  *         -adapted to MSS
  10.  *         -adapted to new utmp database
  11.  *         -adapted to POSIX (MINIX 1.5)
  12.  */
  13.  
  14. #include <sys/types.h>
  15. #include <signal.h>
  16. #include <time.h>
  17. #include <utmp.h>
  18. #include <stdio.h>
  19.  
  20.  
  21. #define Min(a,b)  ((a<b) ? a : b)
  22.  
  23. #define STRING       80        /* lots of room for an argument */
  24. #define MIN       60L        /* seconds per minute */
  25. #define HOUR      (60L*60L)    /* seconds per hour */
  26. #define HALF_DAY  (12L*HOUR)    /* seconds per half day */
  27. #define DAY       (24L*HOUR)    /* seconds per day */
  28.  
  29. /* Set the following to your personal preferences for the
  30.  * time and contents of warnings.
  31.  */
  32. #define INTERVALS 13        /* size of intervals[] */
  33. #define WARNINGS  4        /* size of warnings[] */
  34.  
  35.  
  36. static char *Version = "@(#) LEAVE 1.4 (01/09/90)";
  37. static int intervals[INTERVALS] = {
  38.   -5 * MIN,
  39.   -1 * MIN,
  40.   0,
  41.   MIN,
  42.   2 * MIN,
  43.   3 * MIN,
  44.   4 * MIN,
  45.   5 * MIN,
  46.   6 * MIN,
  47.   7 * MIN,
  48.   8 * MIN,
  49.   9 * MIN,
  50.   10 * MIN
  51. };
  52. static char *warnings[WARNINGS] = {
  53.   "You have to leave within 5 minutes",
  54.   "Just one more minute!",
  55.   "Time to leave!",
  56.   "You're going to be late!"    /* for all subsequent warnings */
  57. };
  58.  
  59.  
  60. #ifdef _BSD
  61. long timezone;
  62. #else
  63. extern long timezone;
  64. #endif
  65.  
  66.  
  67. extern char *ttyname();
  68. extern char *cuserid();
  69.  
  70.  
  71. void Usage()
  72. {
  73.    fprintf(stderr, "Usage: leave [[+]hhmm]\n");
  74.   exit(1);
  75. }
  76.  
  77.  
  78. void Get_Hour_Min(when, hour, min)
  79. char *when;
  80. int *hour;
  81. int *min;
  82. {
  83.   int hour_min;
  84.   int just_min = 0;
  85.  
  86.   switch (sscanf(when, "%d:%d", &hour_min, &just_min)) {
  87.       case 1:
  88.     *hour = hour_min / 100;
  89.     *min = hour_min % 100;
  90.     break;
  91.       case 2:
  92.     *hour = hour_min;
  93.     *min = just_min;
  94.     break;
  95.       default:
  96.     Usage();
  97.   }
  98.  
  99.   if (hour_min < 0 || just_min < 0 || *min > 59) Usage();
  100. }
  101.  
  102.  
  103. int Still_Logged_On(user, tty)
  104. char *user;
  105. char *tty;
  106. {
  107.   FILE *f;
  108.   struct utmp login;
  109.  
  110.   if ((f = fopen(UTMP, "r")) == (FILE *) NULL)
  111.     /* no login/logout records kept */
  112.     return(1);
  113.  
  114.   while (fread(&login, sizeof(struct utmp), 1, f) == 1) {
  115.     if (!strncmp(login.ut_line, tty, 8))
  116.         if (!strncmp(login.ut_name, user, 8)) {
  117.             fclose(f);
  118.             return(1);
  119.         } else {
  120.             fclose(f);
  121.             return(0);
  122.         }
  123.   }
  124.   fclose(f);
  125.   return(0);
  126. }
  127.  
  128.  
  129. main(argc, argv)
  130. int argc;
  131. char *argv[];
  132. {
  133.   char when[STRING];
  134.   long now = time((time_t *)0);
  135.   long leave, delta;
  136.   int hour, min;
  137.   int pid, i;
  138.   char *user = cuserid( (char *) NULL);
  139.   char *tty = ttyname(0) + 5;
  140.  
  141.   /* get the argument string "when" either from stdin, or argv */
  142.   if (argc <= 1) {
  143.     printf("When do you have to leave? ");
  144.     if (fgets(when, STRING, stdin) == NULL || when[0] == '\n') exit(0);
  145.   } else {
  146.     strcpy(when, argv[1]);
  147.     if (argc > 2) strcat(when, argv[2]);
  148.   }
  149.  
  150.   /* determine the leave time from the current time and "when" */
  151.   if (when[0] == '+') {
  152.     Get_Hour_Min(&when[1], &hour, &min);
  153.     leave = now + hour * HOUR + min * MIN;
  154.   } else {
  155.     /* user entered an absolute time */
  156. #ifdef _BSD
  157.     timezone = -localtime(&now)->tm_gmtoff;
  158. #endif
  159.     Get_Hour_Min(&when[0], &hour, &min);
  160.     if (hour >= 1 && hour <= 12) {
  161.         /* 12-hour format: relative to previous midnight or noon */
  162.         leave = now - (now - timezone) % HALF_DAY +
  163.             hour % 12 * HOUR + min * MIN;
  164.         if (leave < now - HOUR)
  165.             leave = leave + HALF_DAY;
  166.         else if (leave < now) {
  167.             printf("That time has already passed!\n");
  168.             exit(1);
  169.         }
  170.     } else if (hour <= 24) {
  171.         /* 24-hour format: relative to previous midnight */
  172.         leave = now - (now - timezone) % DAY +
  173.             hour * HOUR + min * MIN;
  174.         if (leave < now - HOUR)
  175.             leave = leave + DAY;
  176.         else if (leave < now) {
  177.             printf("That time has already passed!\n");
  178.             exit(1);
  179.         }
  180.     } else
  181.         Usage();
  182.   }
  183.  
  184.   printf("Alarm set for %s", ctime(&leave));
  185.  
  186.   if ((pid = fork()) == -1) {
  187.     fprintf(stderr, "leave: can not fork\n");
  188.     exit(1);
  189.   }
  190.   if (pid != 0) exit(0);
  191.  
  192.   /* only the child continues on */
  193.   if (user == NULL || tty == NULL) {
  194.     fprintf(stderr, "leave: Can not determine user and terminal name\n");
  195.     exit(1);
  196.   }
  197.   signal(SIGINT, SIG_IGN);
  198.   signal(SIGQUIT, SIG_IGN);
  199.   signal(SIGTERM, SIG_IGN);
  200.  
  201.   for (;;) {
  202.     if (!Still_Logged_On(user, tty)) exit(0);
  203.  
  204.     /* how much longer until the leave time? */
  205.     delta = leave - time((time_t *)0);
  206.  
  207.     /* which interval are we currently in? */
  208.     for (i = 0; i < INTERVALS; ++i)
  209.         if (delta + intervals[i] > 0) break;
  210.  
  211.     /* if we are within intervals[0] then print a warning If
  212.      * there are more intervals than messages, then use/
  213.      * warnings[WARNINGS-1] for all subsequent messages. */
  214.     if (i > 0)
  215.         printf("\007%s\n", warnings[i > WARNINGS ? WARNINGS - 1 : i - 1]);
  216.  
  217.     if (i == INTERVALS) {
  218.         printf("That was the last time I'll tell you. Bye.\n");
  219.         exit(0);
  220.     }
  221.     /* Sleep until the next interval. For long periods, wake up
  222.      * every hour to check if the user is still on (also required
  223.      * because 16 bit ints don't allow long waits). */
  224.     sleep((int) Min(delta + intervals[i], HOUR));
  225.   }
  226. }
  227.